import copy
import json

import requests
from flask import jsonify, request

from model.cluster import Cluster
from blues.cluster import bp
from config import K8s_API_PREFIX, UA


@bp.route('/api/v1/cluster/<cluster_id>/ingress/')
@bp.route('/api/v1/cluster/<cluster_id>/namespaces/<namespace>/ingress/')
def GetIngressList(cluster_id, namespace=""):
    # 初始化集群
    c = Cluster()
    cluster = c.find_by_id(cluster_id)
    # 调用k8s apiserver
    if namespace:
        url = cluster['apiserver'] + "/apis/extensions/v1beta1/namespaces/" + namespace + "/ingresses"
    else:
        url = cluster['apiserver'] + "/apis/extensions/v1beta1/ingresses"

    headers = {"Authorization": "Bearer " + cluster['token'], "User-Agent": UA}
    response = requests.get(url=url, headers=headers, verify=False)
    # print(response.text)
    data = response.json()
    # print(data)
    proxy_list = []
    if data['items']:
        for i in data['items']:  # 遍历每一个ingress
            tmp_dict = {
                'creat_time': i['metadata']['creationTimestamp'],
                'name': i['metadata']['name'],
                'namespace': i['metadata']['namespace']
            }
            for j in range(len(i['spec']['rules'])):
                tmp_dict['host'] = i['spec']['rules'][j]['host'] if 'host' in i['spec']['rules'][j].keys() else ''
                tmp_dict['rewrite'] = ''
                if 'nginx.ingress.kubernetes.io/rewrite-target' in i['metadata']['annotations'].keys():
                    tmp_dict['rewrite'] = i['metadata']['annotations']['nginx.ingress.kubernetes.io/rewrite-target']
                for k in range(len(i['spec']['rules'][j]['http']['paths'])):
                    tmp_dict['path'] = i['spec']['rules'][j]['http']['paths'][k]['path']
                    tmp_dict['back_svc'] = i['spec']['rules'][j]['http']['paths'][k]['backend']['serviceName']
                    tmp_dict['back_port'] = i['spec']['rules'][j]['http']['paths'][k]['backend']['servicePort']
                    tmp_dict['rule_index'] = j
                    tmp_dict['path_index'] = k

                    proxy_list.append(copy.deepcopy(tmp_dict))
                    # print(tmp_dict)
        # 获取url里的query参数 并对结果进行过滤
        q_ingress = request.args.get('q_ingress')
        q_namespace = request.args.get('q_namespace')
        q_host = request.args.get('q_host')
        q_path = request.args.get('q_path')
        q_svc = request.args.get('q_svc')

        del_list = []
        for x in range(len(proxy_list)):
            if q_ingress and (proxy_list[x]['name']) != q_ingress:
                del_list.append(x)
                continue
            if q_namespace and (proxy_list[x]['namespace']) != q_namespace:
                del_list.append(x)
                continue
            if q_host and (proxy_list[x]['host']) != q_host:
                del_list.append(x)
                continue
            if q_path and (q_path not in proxy_list[x]['path']):
                del_list.append(x)
                continue
            if q_svc and (q_svc not in proxy_list[x]['back_svc']):
                del_list.append(x)
                continue
        print(del_list)
        del_list.sort(reverse=True)
        print(del_list)
        if del_list:
            for x in del_list:
                del proxy_list[x]

    res = {"code": 0, "count": len(proxy_list), "data": proxy_list}

    return jsonify(res)


@bp.route('/api/v1/cluster/<cluster_id>/namespaces/<namespace>/ingressname/')
def GetIngressNameList(cluster_id, namespace=""):
    c = Cluster()
    cluster = c.find_by_id(cluster_id)
    # 调用k8s apiserver
    url = cluster['apiserver'] + "/apis/extensions/v1beta1/namespaces/" + namespace + "/ingresses"
    headers = {"Authorization": "Bearer " + cluster['token'], "User-Agent": UA}
    response = requests.get(url=url, headers=headers, verify=False)
    # print(response.text)
    data = response.json()
    # print(data)
    proxy_list = []
    if data['items']:
        for i in data['items']:
            rule_list = []
            tmp_dict = {
                'creat_time': i['metadata']['creationTimestamp'],
                'name': i['metadata']['name'],
                'namespace': i['metadata']['namespace'],
                'rules': rule_list,
                'rewrite': ''
            }
            if 'nginx.ingress.kubernetes.io/rewrite-target' in i['metadata']['annotations'].keys():
                tmp_dict['rewrite'] = i['metadata']['annotations']['nginx.ingress.kubernetes.io/rewrite-target']
            for j in range(len(i['spec']['rules'])):
                tmp_rule = {}
                tmp_rule['rule_index'] = j
                tmp_rule['host'] = i['spec']['rules'][j]['host'] if 'host' in i['spec']['rules'][j].keys() else ''
                rule_list.append(tmp_rule)

            proxy_list.append(tmp_dict)
            # print(tmp_dict)

    res = {"code": 0, "count": len(proxy_list), "data": proxy_list}

    return jsonify(res)


@bp.route('/api/v1/cluster/<cluster_id>/ingress/<namespace>/<name>/<int:rule_index>/<int:path_index>',
          methods=['POST', 'PATCH', 'DELETE'])
def Ingress(cluster_id, namespace, name, rule_index, path_index):
    body = request.json
    print(body)

    c = Cluster()
    cluster = c.find_by_id(cluster_id)
    # 调用k8s apiserver， 获取此ingress的资源声明
    url = cluster['apiserver'] + "/apis/extensions/v1beta1/namespaces/" + namespace + "/ingresses/" + name
    headers = {"Authorization": "Bearer " + cluster['token'], "User-Agent": UA}
    response = requests.get(url=url, headers=headers, verify=False)
    # print(response.text)
    data = response.json()
    spec = data['spec']
    print(spec)

    # 根据method进行分支判断（POST：更新，del：删除）
    headers["Content-Type"] = "application/merge-patch+json"
    if request.method == 'PATCH':
        # 根据传参body里的json信息，修改原ingress资源声明
        if (not body['host']) and ('host' in spec['rules'][rule_index].keys()):
            del spec['rules'][rule_index]['host']
        else:
            spec['rules'][rule_index]['host'] = body['host']

        data['metadata']['annotations']['nginx.ingress.kubernetes.io/rewrite-target'] = body['rewrite']
        spec['rules'][rule_index]['http']['paths'][path_index]['path'] = body['path']
        spec['rules'][rule_index]['http']['paths'][path_index]['backend']['serviceName'] = body['svc_name']
        spec['rules'][rule_index]['http']['paths'][path_index]['backend']['servicePort'] = body['svc_port']
    elif request.method == 'DELETE':
        del spec['rules'][rule_index]['http']['paths'][path_index]
        if len(spec['rules'][rule_index]['http']['paths']) == 0:
            del spec['rules'][rule_index]
            if len(spec['rules']) == 0:
                response = requests.delete(url=url, headers=headers, verify=False)
                print(response.text)
                return response.json()

    # 再使用patch方法修改原始deployment资源声明
    print(spec)
    response = requests.patch(url=url, headers=headers, data=json.dumps(data), verify=False)
    # print(response.text)
    return response.json()


@bp.route('/api/v1/proxy/add', methods=['POST'])
def addIngress():
    body = request.json
    print(body)
    cluster_id = body['cluster_id']
    namespace = body['namespace']
    ingress_checked = body['ingress_checked']  # existIngress newIngress
    ingress_name = body['ingress_name']
    ingress_rewrite = body['ingress_rewrite']
    rule_checked = body['rule_checked']  # existRule newRule
    rule_index = body['rule_index']
    host = body['host']
    path = body['path']
    back_svc = body['back_svc']
    back_port = body['back_port']

    # 初始化集群
    c = Cluster()
    cluster = c.find_by_id(cluster_id)
    # 初始化调用k8s apiserver时候的headers
    headers = {"Authorization": "Bearer " + cluster['token'], "User-Agent": UA}

    if ingress_checked == 'newIngress':
        ingress_obj = {
            "kind": "Ingress",
            "apiVersion": "extensions/v1beta1",
            "metadata": {
                "name": ingress_name,
                "namespace": namespace,
                "annotations": {
                    "nginx.ingress.kubernetes.io/rewrite-target": ingress_rewrite
                }
            },
            "spec": {
                "rules": [
                    {
                        "host": host,
                        "http": {
                            "paths": [
                                {
                                    "path": path,
                                    "pathType": "Prefix",
                                    "backend": {
                                        "serviceName": back_svc,
                                        "servicePort": back_port
                                    }
                                }
                            ]
                        }
                    }
                ]
            }
        }
        # 调用k8s apiserver， 获取此ingress的资源声明
        url = cluster['apiserver'] + "/apis/extensions/v1beta1/namespaces/" + namespace + "/ingresses"
        response = requests.post(url=url, json=ingress_obj, headers=headers, verify=False)
        print(response.text)
        # data = response.json()
    elif ingress_checked == 'existIngress':
        # 获取已经存在ingress的数据
        url = cluster['apiserver'] + "/apis/extensions/v1beta1/namespaces/" + namespace + "/ingresses/" + ingress_name
        response = requests.get(url=url, headers=headers, verify=False)
        print(response.text)
        exist_ingress = response.json()

        new_path = {
            "path": path,
            "pathType": "Prefix",
            "backend": {
                "serviceName": back_svc,
                "servicePort": back_port
            }
        }
        new_rule = {
            "host": host,
            "http": {
                "paths": [
                    {
                        "path": path,
                        "pathType": "Prefix",
                        "backend": {
                            "serviceName": back_svc,
                            "servicePort": back_port
                        }
                    }
                ]
            }
        }

        if rule_checked == 'existRule':
            exist_ingress['spec']['rules'][rule_index]['http']['paths'].append(new_path)
        elif rule_checked == 'newRule':
            exist_ingress['spec']['rules'].append(new_rule)

        url = cluster['apiserver'] + "/apis/extensions/v1beta1/namespaces/" + namespace + "/ingresses/" + ingress_name
        headers["Content-Type"] = "application/merge-patch+json"
        response = requests.patch(url=url, json=exist_ingress, headers=headers, verify=False)
        print(response.text)

    return jsonify({"code": response.status_code})
